import { Matrix3 } from "../utils/Matrix3";
import { Webgl2DBase } from "./Webgl2DBase";

/*
 * @Author: Snow
 * @Date: 2021-09-12 11:53:25
 * @Description: 
 */
export class Webgl2DMatrix3 extends Webgl2DBase{

    public uViewMatrix:WebGLUniformLocation;

    public override initUITools():void{
        //super.initUITools();
        this.createSlider("anchorX",{value: 1, slide: this.onUpateSlide(this,"anchorX"), min: 0, max: 640, step: 1, precision: 0})
        this.createSlider("anchorY",{value: 1, slide: this.onUpateSlide(this,"anchorY"), min: 0, max: 640, step: 1, precision: 0})

        this.createSlider("x",{value: 1, slide: this.onUpateSlide(this,"x"), min: 0, max: 640, step: 1, precision: 0})
        this.createSlider("y",{value: 0, slide: this.onUpateSlide(this,"y"), min: 0, max: 480, step: 1, precision: 0})
        this.createSlider("scaleX",{value: 1, slide: this.onUpateSlide(this,"scaleX"), min: 0, max: 2, step: 0.01, precision: 2})
        this.createSlider("scaleY",{value: 1, slide: this.onUpateSlide(this,"scaleY"), min: 0, max: 2, step: 0.01, precision: 2})
        this.createSlider("rotation",{value: 0, slide: this.onUpateSlide(this,"rotation"), min: 0, max: 480, step: 1, precision: 0})
        

        this.uiParam = {x:0,y:0,rotation:0,scaleX:1,scaleY:1,anchorX:0,anchorY:0};
    }

    public override initGLSL():void{
        this.vsSource = `
            attribute vec2 aPosition;

            //uniform mat4 uModelViewMatrix;
            //uniform mat3 uProjectionMatrix;
            uniform mat3 uViewMatrix;

            //varying lowp vec4 vColor;

            void main() {
            
                gl_Position = vec4((uViewMatrix * vec3(aPosition,1)).xy,0,1);

            }
        `;
        
        this.fsSource = `
            precision mediump float;
            uniform vec4 uColor;
            void main() {
                gl_FragColor = uColor;
            }
        `;
    }

    public override initProgramInfo():any{
        this.aPositionLoc = this.gl.getAttribLocation(this.shaderProgram,"aPosition");
        
        this.uColorLoc = this.gl.getUniformLocation(this.shaderProgram,"uColor");
        
        this.uViewMatrix = this.gl.getUniformLocation(this.shaderProgram,"uViewMatrix");
        return null;
    }

    public override draw():void{
        const gl = this.gl;
        gl.viewport(0,0,gl.canvas.clientWidth,gl.canvas.clientHeight);
        gl.clearColor(1,1,1,1);
        gl.clearDepth(1.0);
		gl.enable(gl.DEPTH_TEST);
		gl.depthFunc(gl.LEQUAL);
		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        const pos:number[] = [
             // 左竖
            0, 0,
            30, 0,
            0, 150,
            0, 150,
            30, 0,
            30, 150,
    
            // 上横
            30, 0,
            100, 0,
            30, 30,
            30, 30,
            100, 0,
            100, 30,
    
            // 中横
            30, 60,
            67, 60,
            30, 90,
            30, 90,
            67, 60,
            67, 90,
        ];

        const posBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER,posBuffer);
        gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(pos),gl.STATIC_DRAW);
        gl.enableVertexAttribArray(this.aPositionLoc);
        {
            gl.vertexAttribPointer(this.aPositionLoc,2,gl.FLOAT,false,0,0);
        }

        //顶点
        const indexs = [
            0,1,2,3,4,5,
            6,7,8,9,10,11,
            12,13,14,15,16,17
        ];

        const indexsBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexsBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indexs),gl.STATIC_DRAW);


        gl.useProgram(this.shaderProgram);

        

        let x = this.uiParam["x"];
        let y = this.uiParam["y"];
        let rotation = this.uiParam["rotation"];
        let scaleX = this.uiParam["scaleX"];
        let scaleY = this.uiParam["scaleY"];
        let anchorX = this.uiParam["anchorX"];
        let anchorY = this.uiParam["anchorY"];

        
        const resolution:number[] = [
            gl.canvas.width,gl.canvas.height,
        ]

        let angleInRadians = rotation *Math.PI / 180;

        let matrix:number[] = Matrix3.create();
        
        let projectionMatrix:number[] = Matrix3.projection(resolution[0],resolution[1]);
        
        let translationMatrix:number[] = Matrix3.translation(x,y);
        
        let rotationMatrix:number[] = Matrix3.rotation(angleInRadians);

        let scalingMatrix:number[] = Matrix3.scaling(scaleX,scaleY);

        let anchorMatrix:number[] = Matrix3.translation(-anchorX,-anchorY);
        matrix = Matrix3.multiply(matrix,projectionMatrix);
        matrix = Matrix3.multiply(matrix,translationMatrix);
        matrix = Matrix3.multiply(matrix,rotationMatrix);
        matrix = Matrix3.multiply(matrix,scalingMatrix);
        matrix = Matrix3.multiply(matrix,anchorMatrix);


        gl.uniformMatrix3fv(this.uViewMatrix,false,new Float32Array(matrix));

        gl.uniform4fv(this.uColorLoc,new Float32Array([1,0,0,1]));

        //gl.drawArrays(gl.TRIANGLES,0,6);
        gl.drawElements(gl.TRIANGLES,18,gl.UNSIGNED_SHORT,0);
    }

}